/** 发布订阅模式：订阅者把订阅的事件对应的处理函数存放到数组中，
 * 发布者只需要发布对应的事件名，事件中心就会把注册的处理函数依次执行；
 */
/** 被观察者 */
function Subject() {
    this.observers = [];
}

Subject.prototype = {
    /** 订阅 */
    subscribe: function(observer) {
        this.observers.push(observer);
    },

    /** 取消订阅 */
    unsubscribe: function(observerToRemove) {
        this.observers = this.observers.filter(observer => 
            observer !== observerToRemove
        )
    },

    /** 通知 */
    notify: function() {
        this.observers.forEach(observer => observer())
    }
}

const subject = new Subject();

function observer1() {
    console.log('Observer 1 firing!')
}

function observer2() {
    console.log("Observer 2 firing!")
}

subject.subscribe(observer1);
subject.subscribe(observer2);
console.log(subject);
subject.notify();

subject.unsubscribe(observer2);
console.log(subject);
subject.notify();


// 发布订阅模式升级版本
function SubjectPro() {
    this.events = [];
}

SubjectPro.prototype = {
    subscribe: function(event, option){
        let {once = false, priority = 0} = option;
        this.events.push({event, once, priority});
        this.events.sort((a,b) => b.priority > a.priority)
    },
    unsubscribe: function(eventToRemove){
        this.events = this.events.filter((event) =>
            event !== eventToRemove
        )
    },
    publish: function(data){
        const current = [...this.events];
        for(let event of current) {
            Promise.resolve().then(() => 
                event.event(data)
            )
            if(event.once)
                this.unsubscribe(event);
        }
    }
}

const subjectPro = new SubjectPro();

function onlyOnce(data) {
    console.log('只执行一次', data);
}

subjectPro.subscribe(onlyOnce,{once:true});
subjectPro.publish('一次');
subjectPro.publish('二次');
